/**
 * Promise.finally 实例方法 定义到原型上 返回一个新的 promise 实例
 * es9 node 11 版本支持
 * 1) then 的变形，传入的函数无论成功失败都会执行
 * 2) 在 then 中执行 cb 回调使用 Promise.resolve(cb()) 执行，这样做目的是当 cb 是一个 promise 时会等待这个 promise 执行完成
 */

Promise.prototype.finally = function (cb) {
  // 注意：cb 可能是普通值/函数
  if (typeof cb !== 'function') {
    return this
  } else {
    // 直接调用当前 promise 的 then 方法返回一个新的 promise
    return this.then(
      // 考虑到 cb() 调用可能返回一个 promise，这时候就需要使用 Promise.resolve 等待这个 cb() 执行完成返回一个成功的结果为 cb() 返回值的 promise，然后再调用这个 promise.then
      data => Promise.resolve(cb()).then(() => data),
      err => Promise.resolve(cb()).then(() => { throw err })
    )
  }
}

// 测试案例一：pending 状态调用 finally
// let p1 = new Promise(resolve => { })
// console.log(p1.finally())

// 测试案例二：测试 cb 传入一个 非 Promise 实例
// let p2 = new Promise(resolve => {
//   setTimeout(() => {
//     resolve(3)
//   }, 3000)
// })
// p2.finally({}).then(res => {
//   console.log(res)
// }, err => {
//   console.log('err：' + err)
// })

let testP = new Promise((resolve, reject) => {
  reject(1000)
})

// 测试案例三：测试 cb 传入一个函数
testP.finally(() => {
  console.log('最终的');
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('大千世界无奇不有')
    }, 4000)
  })
}).then(res => {
  console.log(res)
}, err => {
  console.log('err：' + err)
})

